<?php
/**
 * Created by PhpStorm.
 * User: zyark
 * Date: 2018/1/24
 * Time: 16:21
 */

namespace app\common\utils;


/**
 * 微信公众号操作类
 */
class WeChatUtils
{
    //表示QRCode的类型
    const QRCODE_TYPE_TEMP = 1;
    const QRCODE_TYPE_LIMIT = 2;
    const QRCODE_TYPE_LIMIT_STR = 3;


//    const BASE_URL='http://www.galaxy1234.com/HappyShop/';
    const BASE_URL='http://www.jipintc.com/';

    //网页授权回调URL
    const REDIRECT_URI = 'index.php/index/we_chat/html_return';
//    const REDIRECT_URI = 'WeChat.php';
    const HTML_SCOPE = 'snsapi_userinfo';
//    const HTML_SCOPE = 'snsapi_base';
    private $_appid;
    private $_appsecret;
    private $_token;// 公众平台请求开发者时需要标记

    private $_msg_template = array(
        'text' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>',//文本回复XML模板
        'image' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>',//图片回复XML模板
        'music' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>',//音乐模板
        'news' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>%s</ArticleCount><Articles>%s</Articles></xml>',// 新闻主体
        'news_item' => '<item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>',//某个新闻模板
    );


    public function __construct($appid, $appsecret, $token)
    {
        $this->_appid = $appid;
        $this->_appsecret = $appsecret;
        $this->_token = $token;
    }

    /**
     * 创建菜单
     * @param $menu 　菜单数据
     * @return 成功返回ture,否则返回false
     */
    public function createMenu($menu)
    {
        $token = $this->getAccessToken();
//        var_dump($token);
        $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" . $token;
        $data = $menu;
        $result = $this->requestHttp($url, $data);
        $result_obj = json_decode($result);
        echo '<br><br>';
        var_dump($result_obj);
        echo '<br><br>' . $result_obj->errcode;
        if (isset($result_obj) && $result_obj->errcode == 0) {
            return true;
        } else {
            echo $result_obj->errmsg, '<br>';
            return false;
        }
    }

    /**
     * 删除菜单
     * @return 成功返回ture,否则返回false
     */

    public function deleteMenu()
    {
        $token = $this->getAccessToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $token;
        $result = $this->requestHttp($url);
        $result_obj = json_decode($result);
        if ($result_obj->errcode == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取token
     * @param string $token_file 本地保存token的文件名,默认为./access_token
     * @return bool|string 获取成功返回token字符串,失败返回false
     */
    public function getAccessToken($token_file = './access_token')
    {
        $life_time = 7200;//token过期时间
        if (file_exists($token_file) && (time() - filemtime($token_file)) < $life_time) {
            //从文件中获取有效的token
            return file_get_contents($token_file);
        }
        //获取token的url
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $this->_appid . '&secret=' . $this->_appsecret;
        //向该URL发起GET请求
        $result = $this->requestHttp($url);
        //获取token失败
        if (!$result)
            return false;
        var_dump($result);
        //获取成功
        $result_obj = json_decode($result);
        //写入文件
//        if (!file_exists($token_file)) {
//            mkdir($token_file);
//        }
        file_put_contents($token_file, $result_obj->access_token);
        return $result_obj->access_token;
    }


    /**
     * 获取jsapi_ticket
     * @param string $ticket_file 本地保存ticket的文件名,默认为./access_ticket
     * @return bool|string 获取成功返回ticket字符串,失败返回false
     */
    public function getJsApiTicket($ticket_file = './access_ticket')
    {
        $life_time = 7200;//ticket过期时间
        if (file_exists($ticket_file) && (time() - filemtime($ticket_file)) < $life_time) {
            //从文件中获取有效的ticket
            return file_get_contents($ticket_file);
        }
        //获取token
        $access_token = $this->getAccessToken();
        //获取ticket的url
        $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $access_token . '&type=jsapi';
        //向该URL发起GET请求
        $result = $this->requestHttp($url);
        //获取ticket失败
        if (!$result)
            return false;
        //获取成功
        $result_obj = json_decode($result);
        //写入文件
//        if (!file_exists($ticket_file)) {
//            mkdir($ticket_file);
//        }
        file_put_contents($ticket_file, $result_obj->ticket);
        return $result_obj->ticket;
    }

    /**
     * 获取用户同意授权的Code
     * @param $state  用户同意后带的参数
     */
    public function getUserCode($state){
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->_appid.'&redirect_uri='.self::BASE_URL.self::REDIRECT_URI.'&response_type=code&scope='.self::HTML_SCOPE.'&state='.$state.'#wechat_redirect';

        //$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->_appid.'&redirect_uri='.self::BASE_URL.self::REDIRECT_URI.'&response_type=code&scope='.self::HTML_SCOPE.'&state='.$state.'#wechat_redirect';
//        echo $url;
        header('Location: '.$url);
    }

    public function getUserCodeByUrl($state,$url){
        $base_url = $this->makeUrl($state,$url);
        header('Location: '.$base_url);
    }


    private function makeUrl ($state,$baseUrl) {
//        $baseUrl = urlencode($baseUrl);
        $url['appid'] = $this->_appid;
        $url['redirect_uri'] = $baseUrl;
        $url['response_type'] = 'code';
        $url['scope'] = 'snsapi_userinfo';     //snsapi_base 只获取用户openid  snsapi_userinfo 弹出授权窗口 可获取用户地区 性别 昵称等信息
        if(empty($state)){
            $url['state'] = rand(5, 1500)."#wechat_redirect";
        }else{
            $url['state'] = $state."#wechat_redirect";
        }
        $newsUrl = $this->makeUrlParam($url);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?".$newsUrl;
    }

    protected function makeUrlParam ($data) {
        $url = "";
        foreach ($data as $key => $value) {
            $url .= $key . "=" .$value ."&";
        }
        $url = trim($url,"&");
        return $url;
    }


    /**
     * {
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE"
    }
     * @param $code  用户网页授权code
     * 获取网页access_token
     * @return bool|string 获取成功返回json数据,失败返回false
     */
    public function getHtmlAccessToken($code){
        $life_time = 7200;//token过期时间
        if(isset($_SESSION['GET_HTML_TOKE_TIME'])){
            $get_time = $_SESSION['GET_HTML_TOKE_TIME'];
//        $_SESSION['GET_HTML_TOKE_TIME'] = '';
            if(isset($_SESSION['HTML_TOKE_JSON']) && (time() - $get_time) < $life_time){
                return $_SESSION['HTML_TOKE_JSON'];
            }
        }
        //获取token的url
        $url= 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->_appid.'&secret='.$this->_appsecret.'&code='.$code.'&grant_type=authorization_code';
        //向该URL发起GET请求
        $result = $this->requestHttp($url);
        //获取token失败
        if (!$result)
            return false;
        $result_obj = json_decode($result);
        if(!empty($result_obj->errcode)){
            return false;
        }
        $_SESSION['HTML_TOKE_JSON'] = $result_obj;
        $_SESSION['GET_HTML_TOKE_TIME'] = time();
        return $result_obj;
    }

    /**
     * {
    "openid":" OPENID",
    " nickname": NICKNAME,
    "sex":"1",
    "province":"PROVINCE"
    "city":"CITY",
    "country":"COUNTRY",
    "headimgurl":"",
    "privilege":[
    "PRIVILEGE1"
    "PRIVILEGE2"
    ],
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
    }
     * @param $access_token  网页token
     * @param $openId 用户oppenId
     * @return bool|mixed  获取成功返回json数据,失败返回false
     */
    public function getUserInfo($access_token,$openId){
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openId.'&lang=zh_CN';
        $result = $this->requestHttp($url);
        //获取token失败
        if (!$result)
            return false;
        //获取成功
        $result_obj = json_decode($result);
        return $result_obj;
    }
    /**
     * 获取随机编码
     * @param int $length　默认长度16位
     * @return string 随机编码
     */
    public function getRandCode($length = 16)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $randCode = '';
        for ($i = 0; $i < $length; $i++) {
            $randCode .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $randCode;
    }

    /**
     * 提交数据获取ticket
     * @param $content 内容标识
     * @param int $type 二维码微信
     * @param int $expire 　如果是临时二维码，表示其有效期
     * @return 成功返回 ticket,失败返回false
     */
    private function _getQRCodeTicket($content, $type = 1, $expire = 604800)
    {
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
        $type_list = array(
            self::QRCODE_TYPE_TEMP => 'QR_SCENE',
            self::QRCODE_TYPE_LIMIT => 'QR_LIMIT_SCENE',
            self::QRCODE_TYPE_LIMIT_STR => 'QR_LIMIT_STR_SCENE',
        );
        $action_name = $type_list[$type];
        if ($type == self::QRCODE_TYPE_TEMP) {
            //如果是临时二维码,设置有效期
            $data_arr['expire_seconds'] = $expire;
        }
        $data_arr['action_name'] = $action_name;
//        $data_arr['action_info']['scene']['scene_str'] = $content;
        $data_arr['action_info']['scene']['scene_id'] = $content;
        $data = json_encode($data_arr);//将数据转化为json
        $result = $this->requestHttp($url, $data);
        if (!$result) {
            return false;
        }
        //处理响应数据
        $result_obj = json_decode($result);

        return $result_obj->ticket;
    }

    /**
     * 生成二维码$result
     * @param $content 内容标识
     * @param null $file 储存为文件的地址，如果为NULL表示直接输出
     * @param int $type 二维码微信
     * @param int $expire 　如果是临时二维码，表示其有效期
     */
    public function getQRCode($content, $file = NULL, $type = 1, $expire = 604800)
    {
        $ticket = $this->_getQRCodeTicket($content, $type, $expire);
//        //根据ticket获取二维码
        $url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $ticket;
        $result = $this->requestHttp($url);//此时result就是图像内容
        if ($file) {
            file_put_contents($file, $result);
        } else {
            header('Content-Type: image/jpeg');
            echo $result;
        }
    }

    /**
     * 发送Http请求的方法
     * @param string $url URL
     * @param  data $data 发送请求数据,如果为post请求,应该设置该项
     * @param bool $ssl 是否为https协议
     * @return string 响应主体Content
     */
    public function requestHttp($url, $data = NULL, $ssl = true)
    {
        // curl完成
        $curl = curl_init();

        //设置curl选项
        curl_setopt($curl, CURLOPT_URL, $url);//URL
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 FirePHP/0.7.4';
        curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);//user_agent，请求代理信息
        curl_setopt($curl, CURLOPT_AUTOREFERER, true);//referer头，请求来源
        //SSL相关
        if ($ssl) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//禁用后cURL将终止从服务端进行验证
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//检查服务器SSL证书中是否存在一个公用名(common name)。
        }
        if (isset($data)) {
            // 处理post相关选项
            curl_setopt($curl, CURLOPT_POST, true);// 是否为POST请求
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);// 处理请求数据
        }

        curl_setopt($curl, CURLOPT_HEADER, false);//是否处理响应头
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//curl_exec()是否返回响应结果

        // 发出请求
        $response = curl_exec($curl);
        if (false === $response) {
            echo '<br>', curl_error($curl), '<br>';
            return false;
        }
        return $response;
    }

    /**
     * 上传临时文件
     * @param $file 素材
     * @param $type 　文件类型
     * @return 上传成功后的数据
     */
    public function uploadTmp($file, $type)
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=' . $this->getAccessToken() . '&type=' . $type;
        $data['media'] = new \CURLFile($file);
//        echo $data['media'] . '<br>' . $url . '<br><br>';
        $result = $this->requestHttp($url, $data);
        $result_obj = json_decode($result);
        return $result_obj;
    }

    public function getFileList($type,$offset,$count)
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=' . $this->getAccessToken();
//        echo $data['media'] . '<br>' . $url . '<br><br>';
        $data['type'] = $type;
        $data['offset'] = $offset;
        $data['count'] = $count;
        $data = json_encode($data);
        $result = $this->requestHttp($url,$data);
        $result_obj = json_decode($result);
        return $result_obj;
    }

    /**
     * 发送图片消息
     * @param $to 目标用户ID
     * @param $from 来源用户ID
     * @param $file
     * @param bool $is_id
     */
    public function msgImage($to, $from, $file, $is_id = false)
    {
        if ($is_id) {
            $media_id = $file;
        } else {
            //上传图片到微信公众号服务器，获取mediaID
            $result_obj = $this->uploadTmp($file, 'image');
            $media_id = $result_obj->media_id;
        }
        //拼凑图像类消息xml文件
        $response = sprintf($this->_msg_template['image'], $to, $from, time(), $media_id);
        die($response);
    }



    /**
     * 发送文本信息
     * @param $to 目标用户ID
     * @param $from 　来源用户ID
     * @param $content 　内容
     */
    public function msgText($to, $from, $content)
    {
        $response = sprintf($this->_msg_template['text'], $to, $from, time(), $content);
        die($response);
    }

    /**
     * [_msgMusic description]
     * @param  [type] $to             [description]
     * @param  [type] $from           [description]
     * @param  [type] $music_url      [description]
     * @param  [type] $thumb_media_id [description]
     * @param  string $title [description]
     * @param  string $desc [description]
     * @return [type]                 [description]
     */
    public function msgMusic($to, $from, $music_url, $hq_music_url, $thumb_media_id, $title = '', $desc = '')
    {
        $response = sprintf($this->_msg_template['music'], $to, $from, time(), $title, $desc, $music_url, $hq_music_url, $thumb_media_id);
        die($response);
    }

    public function msgNews($FromUserName, $ToUserName, $item_list)
    {
        $item_str = '';
        foreach ($item_list as $item) {
            $item_str .= sprintf($this->_msg_template['news_item'], $item['title'], $item['desc'], $item['picurl'], $item['url']);
        }
        //拼凑整体图文部分
        $response = sprintf($this->_msg_template['news'], $ToUserName,$FromUserName, time(), count($item_list), $item_str);
        die($response);
    }

    /**
     * 给后台管理员发送模板消息
     * @param $open_id
     * @param $message
     */
    public function sendAdminTemplateMessage($open_id,$message){
        $template_id = 'Uwn2zc-Hm7IBlvNMUyX9-CGBuO-7DbEQ7gU6MqH_Ndc';
        $open_id = $open_id.'';
        $data['touser'] = $open_id;
        $data['template_id'] = $template_id;
        $data['data']['first']['value'] = '您有一个新的配送订单';
//        $data['data']['first']['color'] = '#173177';
        $data['data']['OrderSn']['value'] = $message['id'];
//        $data['data']['OrderSn']['color'] = '#173177';
        $data['data']['OrderStatus']['value'] = '未配送';
//        $data['data']['OrderStatus']['color'] = '#173177';
        $data['data']['remark']['value'] = '请尽快去个人中心查看订单详情';
//        $data['data']['remark']['color'] = '#173177';
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$access_token";
        $data = json_encode($data);//将数据转化为json
        $result = $this->requestHttp($url,$data);
//        var_dump($result);
    }



    public function  getNewsList(){

        $url = 'https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=' . $this->getAccessToken();
        $data['type'] = "news";
        $data['offset'] = 0;
        $data['count'] = 10;
        $data = json_encode($data);
        $result = $this->requestHttp($url,$data);//此时result就是图像内容
        $result = json_decode($result);
//        var_dump($result->item[0]->content->news_item[0]);
        return $result->item[0]->content->news_item[0];
    }

    public function getResourceByMediaId($mediaId){
        $url = 'https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=' . $this->getAccessToken();
        $data['media_id'] = $mediaId;
        $data = json_encode($data);
        $result = $this->requestHttp($url, $data);
        $result_obj = json_decode($result);
        return $result_obj;

    }

}